import os
import psutil
import win32net
import win32security
from openpyxl import Workbook, load_workbook
from openpyxl.styles import Font, Alignment
from datetime import datetime


def kill_excel_processes():
    """关闭所有Excel和WPS进程"""
    processes_to_kill = ['excel.exe', 'et.exe', 'wps.exe', 'wpp.exe']
    try:
        for proc in psutil.process_iter(['pid', 'name']):
            if proc.info['name'].lower() in processes_to_kill:
                try:
                    proc.kill()
                    print(f"已终止进程: {proc.info['name']}")
                except (psutil.AccessDenied, psutil.NoSuchProcess):
                    continue
        print("成功关闭所有办公软件进程")
    except Exception as e:
        print(f"终止进程时出错: {str(e)}")


def clean_old_file(filepath):
    """删除旧文件"""
    try:
        if os.path.exists(filepath):
            os.remove(filepath)
            print(f"已删除旧文件: {filepath}")
    except Exception as e:
        print(f"删除文件时出错: {str(e)}")


def ensure_directory(path):
    """确保目录存在"""
    try:
        dir_path = os.path.dirname(path)
        if not os.path.exists(dir_path):
            os.makedirs(dir_path)
            print(f"已创建目录: {dir_path}")
    except Exception as e:
        print(f"创建目录时出错: {str(e)}")
        raise


def get_local_users():
    """获取本地用户列表"""
    try:
        users = []
        resume = 0
        while True:
            result, total, resume = win32net.NetUserEnum(None, 0, 0, resume)
            users.extend([user['name'] for user in result])
            if resume == 0:
                break
        return users
    except Exception as e:
        print(f"获取本地用户失败: {str(e)}")
        raise


def get_user_sid_mapping(users):
    """获取用户SID映射表"""
    sid_map = {}
    for user in users:
        try:
            sid = win32security.LookupAccountName(None, user)[0]
            sid_str = win32security.ConvertSidToStringSid(sid)
            sid_map[user] = sid_str
        except Exception as e:
            print(f"获取用户 {user} SID 失败: {str(e)}")
            sid_map[user] = "N/A"
    return sid_map


def read_source_file(filepath, has_header=True):
    """读取源Excel文件"""
    try:
        wb = load_workbook(filepath, read_only=True)
        ws = wb.active
        start_row = 2 if has_header else 1
        return [str(ws.cell(row=i, column=1).value).strip().lower()
                for i in range(start_row, ws.max_row + 1)
                if ws.cell(row=i, column=1).value]
    except Exception as e:
        print(f"读取源文件失败: {str(e)}")
        raise
    finally:
        if 'wb' in locals():
            wb.close()


def generate_report(local_users, source_users, sid_map):
    """生成报告数据"""
    report_data = []
    missing_count = 0

    for user in local_users:
        user_lower = user.lower().strip()
        if user_lower not in source_users:
            report_data.append({
                "姓名": user,
                "SID": sid_map.get(user, "N/A"),
                "状态": "未找到"
            })
            missing_count += 1

    # 添加统计行
    if report_data:
        report_data.append({
            "姓名": "总数",
            "SID": missing_count,
            "状态": ""
        })

    return report_data


def save_report(data, output_path):
    """保存结果到Excel"""
    try:
        wb = Workbook()
        ws = wb.active
        ws.title = "用户状态"

        # 添加标题
        headers = ["姓名", "SID", "状态"]
        ws.append(headers)

        # 设置标题格式
        for col in range(1, 4):
            ws.cell(row=1, column=col).font = Font(bold=True)

        # 添加数据
        for item in data:
            ws.append([item["姓名"], item["SID"], item["状态"]])

        # 设置统计行格式
        if data:
            last_row = ws.max_row
            for col in range(1, 4):
                cell = ws.cell(row=last_row, column=col)
                cell.font = Font(bold=True)
                cell.alignment = Alignment(horizontal="center")

        # 自动调整列宽
        for column in ws.columns:
            max_length = 0
            column = [cell for cell in column]
            for cell in column:
                try:
                    if len(str(cell.value)) > max_length:
                        max_length = len(cell.value)
                except:
                    pass
            adjusted_width = (max_length + 2)
            ws.column_dimensions[column[0].column_letter].width = adjusted_width

        wb.save(output_path)
        print(f"报告已保存至: {output_path}")
    except Exception as e:
        print(f"保存报告失败: {str(e)}")
        raise


def main():
    # 配置参数
    config = {
        "source_file": r"D:\test\test.xlsx",
        "output_file": r"D:\test\jieguo.xlsx",
        "has_header": True
    }

    try:
        # 预处理
        kill_excel_processes()
        clean_old_file(config["output_file"])
        ensure_directory(config["output_file"])

        # 获取数据
        local_users = get_local_users()
        sid_map = get_user_sid_mapping(local_users)
        source_users = set(read_source_file(config["source_file"], config["has_header"]))

        # 生成报告
        report_data = generate_report(local_users, source_users, sid_map)

        if not report_data:
            print("没有发现未匹配的用户")
            return

        # 保存结果
        save_report(report_data, config["output_file"])

        print("操作成功完成")
    except Exception as e:
        print(f"程序执行失败: {str(e)}")


if __name__ == "__main__":
    print(f"脚本启动时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
    main()
    print(f"脚本完成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
